package com.nervenets.web.controller;

import com.nervenets.aspect.RedisLocker;
import com.nervenets.utils.JodaUtils;
import com.nervenets.web.enumeration.OrderStatus;
import com.nervenets.web.enumeration.OrderType;
import com.nervenets.web.hibernate.dao.UserDao;
import com.nervenets.web.hibernate.domain.user.Order;
import com.nervenets.web.rabbitmq.FlowMessage;
import com.nervenets.web.rabbitmq.FlowType;
import com.nervenets.web.rabbitmq.MessageProducer;
import com.nervenets.web.redis.GlobalService;
import com.nervenets.web.redis.GlobalVariablesService;
import com.nervenets.web.redis.RedisDao;
import com.nervenets.web.redis.domain.global.GlobalRule;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.weixin4j.Weixin;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

/**
 * @author joe
 * Created at 14-7-30 上午9:27
 */
@Component
@EnableScheduling
public class SchedulerTask {
    @Resource
    private MessageProducer messageProducer;
    @Resource
    private UserDao userDao;
    @Resource
    private GlobalService globalService;
    @Resource
    private GlobalVariablesService globalVariablesService;

    /**
     * 每1分钟执行
     */
    @Scheduled(cron = "* */1 * * * *")
    @RedisLocker(lockKey = "SchedulerTask.every5MinutesExecute", holdTime = 5)
    public void every1MinutesExecute() throws Exception {
        System.out.println("SchedulerTask execute...");
        final GlobalRule globalRule = globalVariablesService.getGlobalRule();
        //过期未支付处理
        HashMap<String, Object> params = new HashMap<>();
        params.put("status", OrderStatus.init);
        params.put("lastTime", JodaUtils.getTimestamp() - globalRule.getOrderExpiredPayTime() * 60);
        List<Order> orders = userDao.getAllObjectsByHql("from Order where status = :status and createTime < :lastTime", params, 0, 10);
        for (Order order : orders) {
            order.setStatus(OrderStatus.expired);
            userDao.saveOrUpdate(order);
        }

        //过期未付尾款处理
        params = new HashMap<>();
        params.put("status", OrderStatus.tailConfirm);
        params.put("orderType", OrderType.movie);
        params.put("lastTime", JodaUtils.getTimestamp() - globalRule.getTailConfirmHour() * 60);
        orders = userDao.getAllObjectsByHql("from Order where status = :status and orderType = :orderType and payTime < :lastTime", params, 0, 10);
        for (Order order : orders) {
            order.setStatus(OrderStatus.expiredTailConfirm);
            userDao.saveOrUpdate(order);
            messageProducer.flow(new FlowMessage(order.getUserId(), FlowType.orderExpiredTailConfirm, 0, order.getId()));
        }
    }

    /**
     * 每小时执行
     */
    @Scheduled(cron = "30 0 * * * *")
    @RedisLocker(lockKey = "SchedulerTask.everyHourExecute", holdTime = 3000)
    public void everyHourExecute() throws Exception {
        System.out.println("SchedulerTask.everyHourExecute execute...");
        int startOfLastHour = JodaUtils.getStartOfLastHour();
        //每小时统计用户（总数，活跃，新）

        //每小时更新一次微信OAuthToken
        final Weixin weixin = Global.getWeixin();
        weixin.reLogin();
        globalVariablesService.setWeChatAuthToken(weixin.getOAuthToken());
    }

    /**
     * 每天执行
     *
     * @throws Exception
     */
    @RedisLocker(lockKey = "SchedulerTask.everyDayExecute", holdTime = 7200)
    @Scheduled(cron = "0 0 1 ? * *")
    public void everyDayExecute() throws Exception {
        System.out.println("SchedulerTask.everyDayExecute execute...");

    }

    /**
     * 每周执行
     *
     * @throws Exception
     */
    @RedisLocker(lockKey = "SchedulerTask.everyWeekExecute", holdTime = 7200)
    @Scheduled(cron = "0 0 1 ? * MON")
    public void everyWeekExecute() throws Exception {
        System.out.println("SchedulerTask.everyWeekExecute execute...");
    }


    /**
     * 每月执行一次
     */
    @RedisLocker(lockKey = "SchedulerTask.everyMonthExecute", holdTime = 7200)
    @Scheduled(cron = "0 0 1 1 * *")
    public void everyMonthExecute() {
        System.out.println("SchedulerTask.everyMonthExecute execute...");

    }
}
